import axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from 'axios';
import { layer } from '@layui/layui-vue';
import router from '../router'
import { getToken } from '../library/cookieUtil'

//const hostURL = "https://www.cxuu.top";
const hostURL = "http://localhost:5000";
const apiURL = hostURL + "/api";
const uploadURL = apiURL + "/upload/upload";
type TAxiosOption = {
    timeout: number;
    baseURL: string;
}

const config: TAxiosOption = {
    timeout: 5000,
    baseURL: apiURL
}

const codeMessage = {
    200: '服务器成功返回请求的数据。',
    201: '新建或修改数据成功。',
    202: '一个请求已经进入后台排队（异步任务）。',
    204: '删除数据成功。',
    400: '发出的请求有错误，服务器没有进行新建或修改数据的操作。',
    401: '用户没有权限（令牌、用户名、密码错误）',
    403: '用户得到授权，但是访问是被禁止的。',
    404: '发出的请求针对的是不存在的记录，服务器没有进行操作。',
    406: '请求的格式不可得。',
    410: '请求的资源被永久删除，且不会再得到的。',
    422: '当创建一个对象时，发生一个验证错误。',
    500: '服务器发生错误，请检查服务器。',
    502: '网关错误。',
    503: '服务不可用，服务器暂时过载或维护。',
    504: '网关超时。',
}
class Http {
    service;
    constructor(config: TAxiosOption) {
        this.service = axios.create(config)
        /* 请求拦截 */
        this.service.interceptors.request.use((config: AxiosRequestConfig) => {
            const token = getToken();
            if (token) {
                (config.headers as AxiosRequestHeaders).Authorization = 'Bearer ' + token as string
            } else {
                if (router.currentRoute.value.path !== '/login') {
                    router.push('/login');
                }
            }
            return config
        }, error => {
            console.log("error");
            return Promise.reject(error);
        })

        // 响应拦截
        this.service.interceptors.response.use(
            (response: AxiosResponse<any>) => {
                if (response.data.status == 401) {
                    layer.msg(`登录过期，重新登录`);
                    router.replace({ path: '/login' });
                }
                return response.data
            },
            err => {
                //console.log("er:",err.response);
                if (err.response) {
                    const data = err.response
                    let description
                    switch (err.response.status) {
                        case 401:
                            router.replace({ path: '/login' });
                            description = data.Message || codeMessage[401]
                            break
                        case 403:
                            router.replace({ path: '/error/403' });
                            description = data.Message || codeMessage[403]
                            break
                        case 500:
                            router.replace({ path: '/error/500' });
                            description = data.Message || codeMessage[500]
                            break
                        case 400:                            
                            description = data.Message || codeMessage[400]
                            break
                        case 404:
                            router.replace({ path: '/error/404' });
                            description = data.Message || codeMessage[404]
                            break
                        default:
                            description = data.Message || '未知错误 ' + err.response.status
                            data.url && router.push(data.url)
                    }
                    layer.msg(description);
                    return Promise.reject(new Error(description))
                } else {
                    return Promise.reject(new Error('请求失败'))
                }
            })
    }

    /* GET 方法 */
    get<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.get(url, { params, ..._object })
    }
    /* POST 方法 */
    post<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.post(url, params, _object)
    }
    /* PUT 方法 */
    put<T>(url: string, params?: object, _object = {}): Promise<any> {
        return this.service.put(url, params, _object)
    }
    /* DELETE 方法 */
    delete<T>(url: string, params?: any, _object = {}): Promise<any> {
        return this.service.delete(url, { params, ..._object })
    }


    hostURL() {
        return hostURL;
    }

    uploadURL() {
        return uploadURL;
    }
}

export default new Http(config)